using System;
using System.Collections.Generic;
using System.Text;

namespace Decav.Reality
{
    /// <summary>
    /// Defines the name of a person.
    /// </summary>
    [Serializable]
    public struct PersonName
    {
        /// <summary>
        /// Creates a new persons name.
        /// </summary>
        /// <param name="firstName">The first name.</param>
        /// <param name="lastName">The last name.</param>
        public PersonName(string firstName, string lastName)
        {
            if (firstName == null)
                throw new ArgumentNullException("firstName");

            if (lastName == null)
                throw new ArgumentNullException("lastName");

            _firstName = firstName;
            _lastName = lastName;
        }

        /// <summary>
        /// Attempts to parse a first and last name of a person out.
        /// </summary>
        /// <param name="nameString">The persons full name.</param>
        /// <param name="name">The name result.</param>
        /// <returns>True when successful, else false.</returns>
        public static PersonName Parse(string nameString)
        {
            if (nameString == null)
                throw new ArgumentNullException("nameString");

            PersonName output = PersonName.Empty;
            if (!TryParse(nameString, out output))
                throw new ArgumentException("The name specified is not a valid name.");

            return output;
        }

        /// <summary>
        /// Attempts to parse a first and last name of a person out.
        /// </summary>
        /// <param name="nameString">The persons full name.</param>
        /// <param name="name">The name result.</param>
        /// <returns>True when successful, else false.</returns>
        public static bool TryParse(string nameString, out PersonName name)
        {
            name = PersonName.Empty;
            if (nameString == null)
                return false;


            string[] splitupName = nameString.Split(' ');
            if (splitupName.Length < 2 || nameString.Length < 8)
                return false;

            string firstName = splitupName[0];

            StringBuilder builder = new StringBuilder();
            for (int i = 1; i < splitupName.Length; i++)
            {
                builder.Append(splitupName[i]);

                if (i != splitupName.Length - 1)
                    builder.Append(" ");
            }
            name = new PersonName(firstName, builder.ToString());
            return true;
        }

        private string _firstName;
        private string _lastName;

        /// <summary>
        /// Gets the persons surname.
        /// </summary>
        public string LastName
        {
            get
            {
                return _lastName;
            }
        }

        /// <summary>
        /// Gets the persons first name.
        /// </summary>
        public string FirstName
        {
            get
            {
                return _firstName;
            }
        }

        /// <summary>
        /// Gets the empty value of a persons name.
        /// </summary>
        public static readonly PersonName Empty = new PersonName();

        public override int GetHashCode()
        {
            if (_firstName == null)
                return 0;

            return _firstName.GetHashCode() | _lastName.GetHashCode();
        }

        public override string ToString()
        {
            if (_firstName == null)
                return string.Empty;

            return string.Format("{0} {1}", _firstName, _lastName);
        }

        public override bool Equals(object obj)
        {
            if (obj == null)
                return false;

            if (obj.GetType() != typeof(PersonName))
                return false;

            PersonName name = (PersonName)obj;

            return name._firstName == this._firstName && name._lastName == this._lastName;
        }
    }
}
